#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qmessagebox.h>
#include <qtimer.h>
#include "fmod.h"
#include <QtCore/qmath.h>
#include <QScrollBar>
#include <QTime>
#include <qmath.h>
#include <QMenu>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    buttond = new Buttond;
    buttonl = new Buttonl;
    addtarget = new add_target;
    setFixedSize(1000,600);
    ui->label->setStyleSheet("border:1px solid rgb(39, 174, 96)");
    //比例尺滑块及滑槽样式
    ui->scrollArea->setStyleSheet(
                                         "QScrollArea{border:1px solid rgb(39, 174, 96);background-color:transparent;}"
                                         "QScrollArea QScrollBar:vertical{width:8px;"
                                         "background:transparent;margin:0px,1px,0px,1px;"
                                         "padding-top:0px;padding-bottom:0px;border-radius:4px;}"
                                         "QScrollArea QScrollBar::handle:vertical{background:#27ae60;}"
                                         "QScrollArea QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical{"
                                         "background:transparent;border-radius:4px;}"//设置滑块滑动后一端槽的背景透明
                                         "QScrollArea QScrollBar::add-line:vertical,QScrollBar::sub-line:vertical{"
                                         "height:0px;width:0px;}");//去掉上下箭头
    //背景透明
    ui->scrollAreaWidgetContents->setStyleSheet("background-color:transparent;border:none;");
    arr.append(" 目标数据展示区");
    ui->label_km->setText(QString("单位KM,当前半径范围:%1KM").arg(ui->Slider->value()));
    ui->label_km->setStyleSheet("color: rgb(39, 174, 96)");
    //按钮样式设置
    ui->pushButton_T->setStyleSheet("border:2px groove gray;border-radius:10px;padding:2px 4px;background-color:rgb(39, 174, 96);");
    ui->pushButton_R->setStyleSheet("border:2px groove gray;border-radius:10px;padding:2px 4px;background-color:rgb(39, 174, 96);");
    ui->pushButton_C->setStyleSheet("border:2px groove gray;border-radius:10px;padding:2px 4px;background-color:rgb(39, 174, 96);");
    ui->pushButton_D->setStyleSheet("border:2px groove gray;border-radius:10px;padding:2px 4px;background-color:rgb(39, 174, 96);");
    ui->pushButton_L->setStyleSheet("border:2px groove gray;border-radius:10px;padding:2px 4px;background-color:rgb(39, 174, 96);");
    //设置数据展示区滑块样式
    ui->Slider->setStyleSheet("QSlider::handle:horizontal{\
                                        width: 12px;\
                                        height: 70px;\
                                        margin-top: -20px;\
                                        margin-left: 0px;\
                                        margin-bottom: -20px;\
                                        margin-right: 0px;\
                                        border-image: url(:/pic/slider.png);}\
                                QSlider::groove:horizontal{\
                                         height: 12px;\
                                         left: 5px;\
                                         right: 5px;\
                                         border-color: rgba(255, 255, 255, 0);}");
    connect(&timer, SIGNAL(timeout()),this,SLOT(onTimer()));
    connect(&timer_target,SIGNAL(timeout()),this,SLOT(target_update()));
    connect(&timer_h,SIGNAL(timeout()),this,SLOT(h_update()));
    connect(&timer_l,SIGNAL(timeout()),this,SLOT(l_update()));
    //数据初始化
    center.setX(this->height()/2+60);//中心X坐标赋值
    center.setY(this->height()/2);//中心Y坐标赋值
    r=this->width()>this->height()?this->height()/2-46:this->width()/2-46;//设置半径
    result = FMOD_System_Create(&system);
    result = FMOD_System_Init(system, 32, FMOD_INIT_NORMAL, 0);
    sound = 0;
    channel = 0;
    datal.dir = 45;
    datal.dis = 150;
    datal_dis_temp = 0;
    timer_l.start(400);
    scrollArea_maxh = ui->scrollArea->height();
    wav.resize(2048);
    _curvePlot =new CurvePlot(this);
    ui->music->addWidget(_curvePlot);
    _curvePlot->setAdjustVal(0.5);
    Play();
}

MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::paintEvent(QPaintEvent *event)//重写paintevent
{
    QPainter painter(this);
    QPen pen(QColor(0x27ae60));
    QBrush brush(QColor(0x27ae60));
    painter.drawPixmap(0,0,this->width(),this->height(),QPixmap(":/pic/pic.jpg"));
    painter.setRenderHint(QPainter::Antialiasing, true);//抗锯齿
    //画外圆 
    pen.setWidth(7);
    painter.setPen(pen);
    painter.drawEllipse(center,r+26,r+26);
    //画报警区域
    painter.save();
    this->setAttribute(Qt::WA_TranslucentBackground,true);
    for(int i=0;i<data_d_v.size();i++)
    {
        QPainterPath path,subpath;
        path.addEllipse(center,data_d_v[i].far*r/ui->Slider->value(),data_d_v[i].far*r/ui->Slider->value());
        subpath.addEllipse(center,data_d_v[i].near*r/ui->Slider->value(),data_d_v[i].near*r/ui->Slider->value());
        path -= subpath;
        painter.setClipPath(path);
        int transparency_value;
        //根据不同的警告级别设置透明度
        switch (data_d_v[i].danger) {
            case 1:
                transparency_value = 30;
                break;
            case 2:
                transparency_value = 50;
                break;
            case 3:
                transparency_value = 70;
                break;
            default:
                transparency_value = 30;
                break;
        }
        pen.setColor(QColor(255,0,0,transparency_value));
        pen.setWidth(1);
        brush.setColor(QColor(255,0,0,transparency_value));
        painter.setPen(pen);
        painter.setBrush(brush);
        painter.drawPie(center.x()-r,center.y()-r,2*r,2*r,(-data_d_v[i].stardir+90)*16,(-data_d_v[i].enddir+data_d_v[i].stardir)*16);
        painter.setClipping(false);//关闭区域裁剪
    }
    painter.restore();
    //滑块移动时画中间其他⚪
    pen.setWidth(1);
    pen.setColor(QColor(0x27ae60));
    painter.setPen(pen);
    int value = ui->Slider->value();
    for(int i = 1;i<=value/50 && i!=6;i++)
    {
        double R = r*i*50/value;
        painter.drawEllipse(center,R,R);
        QFont wordfont;
        wordfont.setFamily("宋体");
        wordfont.setPointSize(8);
        QFontMetrics fm(wordfont);
        QRect rec = fm.boundingRect(QString("%1Km").arg(i*50));
        painter.drawText(QPoint(center.x()-R,center.y()+rec.height()/2),QString("%1KM").arg(i*50));
        painter.drawText(QPoint(center.x()+R-rec.width()-5,center.y()+rec.height()/2),QString("%1KM").arg(i*50));
    }
    //移动坐标原点
    painter.translate(center);
    //画刻度线
    painter.save();
    int size = 0;
    pen.setWidth(1);
    painter.setPen(pen);
    for(int i=0;i<360;i++)
    {
        if(!(i%10))
        {
            painter.save();//保存当前painter状态
            painter.setFont(QFont("黑体",12));//设置字体
            painter.translate(0,-r-10);//将中心点移动到距边缘40处
            painter.drawText(QPoint(-15,+6),QString("%1").arg(i, 3, 10, QLatin1Char('0')));//画数字，将Point的坐标设置到数字中心，消除因数字大小造成位置偏差
            painter.restore();//将painter状态还原
        }
       if(!(i%90))
          size = 40;
       else if(!(i%10))
          size = 20;
       else if(!(i%5))
          size = 15;
       else
          size = 10;
       painter.drawLine(r-size,0,r,0);
       painter.rotate(1);
    }
    painter.restore();
    //画激光
    painter.save();
    QPainterPath p;
    p.addEllipse(QPoint(0,0),r,r);
    painter.setClipPath(p);//划定目标移动范围
    pen.setWidth(5);
    pen.setColor(Qt::yellow);
    pen.setCapStyle(Qt::RoundCap);
    painter.setPen(pen);
    painter.rotate(datal.dir);
    painter.drawLine(QPoint(0,0),QPoint(0,-datal_dis_temp*r/ui->Slider->value()));
    painter.restore();
    //画中心点实心圆
    brush.setColor(QColor(0x27ae60));
    painter.setBrush(brush);
    painter.drawEllipse(QPoint(0,0),5,5);
    //画指针
    QPolygon polygon;
    polygon.setPoints(3,-3,0,3,0,0,-r);//设置三角形三点坐标
    painter.save();//保存painter旋转前的状态
    painter.rotate(ui->Slider->value());//painter旋转角度，角度值为游标的当前值
    painter.drawPolygon(polygon);
    painter.restore();//将painter状态还原
    //还原坐标远点  画游标滑块
    painter.translate(-center.x(),-center.y());
    int x = ui->Slider->pos().x()+11;
    int y = ui->Slider->pos().y();
    int l,j;
    painter.drawLine(x,y-10,x+300,y-10);
    painter.drawLine(x,y+ui->Slider->geometry().height()+10,x+300,y+ui->Slider->geometry().height()+10);
    for(int i=0;i<=50;i++)
    {
        l=x+300/50*i;
        if(i%5)
            j=7;
        else
        {
            j=15;
            QFont wordfont;
            wordfont.setFamily("宋体");
            wordfont.setPointSize(10);
            QFontMetrics fm(wordfont);
            QRect rec = fm.boundingRect(QString("%1").arg(i*6));
            if(!i)
                painter.drawText(l-rec.width()/2,y+40,"1");
            else
                painter.drawText(l-rec.width()/2,y+40,QString("%1").arg(i*6));
        }
        painter.drawLine(l,y-10,l,y-10+j);
        painter.drawLine(l,y+ui->Slider->geometry().height()+10-j,l,y+ui->Slider->geometry().height()+10);
    }
    //画目标
    painter.translate(center);
    painter.setClipPath(p);//划定目标移动范围
    pen.setWidth(1);
    QColor color;
    for(int i=0;i<target.count();i++)
    {
        if (target[i].color == 0)
            color = Qt::red;
        else
            color = QColor(target[i].color);
        pen.setColor(color);
        brush.setColor(color);
        int value = ui->Slider->value();
        QPoint point = QPoint(target[i].x*target[i].Slidervalue/value,target[i].y*target[i].Slidervalue/value);
        //画目标圆点
        painter.setPen(pen);
        painter.setBrush(brush);
        painter.drawEllipse(point,3,3);
        //画方位指示三角形
        painter.save();
        painter.translate(point.x(),point.y());//将中心点移动到对应坐标绘制方位指示三角形
        QPolygon polygon;
        polygon.setPoints(3,8,4,8,-4,12,0);//设置三角形三点坐标
        painter.rotate(target[i].direction-90);//旋转到对应方位
        painter.drawPolygon(polygon);//绘制三角形
        painter.restore();
        //画牵引线
        pen.setStyle(Qt::DashLine);
        painter.setPen(QPen(pen));
        painter.drawLine(point,QPoint(point.x()+15,point.y()+15));
        painter.drawLine(QPoint(point.x()+15,point.y()+15),QPoint(point.x()+25,point.y()+15));
        painter.drawText(QPoint(point.x()+25,point.y()+30),QString("编号=%1").arg(target[i].id));
        painter.drawText(QPoint(point.x()+25,point.y()+50),QString("速度=%1KM/S").arg(target[i].speed));
    }
    painter.setClipping(false);
}
//播放音乐
void MainWindow::Play()
{
    QString strFile = QCoreApplication::applicationDirPath()+"/1.mp3";
    if (!QFile::exists(strFile))
    {
        QMessageBox::warning(this,"提示","文件不存在！");
        return;
    }
    FMOD_System_CreateSound(system, strFile.toLocal8Bit().data(), FMOD_SOFTWARE | FMOD_CREATESAMPLE, 0, &sound);
    FMOD_Sound_SetMode(sound, FMOD_LOOP_OFF);
    FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, sound, false, &channel);
    uint length;
    FMOD_Sound_GetLength(sound, &length, FMOD_TIMEUNIT_MS);
    length /= 1000;
    FMOD_System_Update(system);
    timer.start(300);
}
//绘制音乐波形图和柱状图的时钟
void MainWindow::onTimer()
{
    float *dat = new float[16384];
    FMOD_System_GetWaveData(system, dat, 16384, 0);
    for (int i = 0, n = 0; i < 16384; i+= 8, n++)
        wav[n] = dat[i];
    _curvePlot->outPut(wav);
    ui->plotall1->outputline(wav);
    ui->plotall2->outputline(wav);
    delete [] dat;
    if (channel)
    {
        uint pos;
        FMOD_Channel_GetPosition(channel, &pos, FMOD_TIMEUNIT_MS);
        pos /= 1000;
        FMOD_BOOL isPlay;
        FMOD_Channel_IsPlaying(channel, &isPlay);
        if (!isPlay)
        {
            Play();
        }
    }
}
//更新容器内目标的坐标值的时钟
void MainWindow::target_update()
{
    if(target.isEmpty())
    {
        timer_target.stop();
        return;
    }
    for(int i=0;i<target.count();i++)
    {
        target[i].x = (target[i].x)+target[i].speed*qCos((target[i].direction-90)/180.0*M_PI);
        target[i].y = (target[i].y)+target[i].speed*qSin((target[i].direction-90)/180.0*M_PI);
        if(target[i].x<-r-70 || target[i].x>r+70 || target[i].y>r+70 || target[i].y<-r-70)
            target.remove(i);
    }
    update();
}
//游标滑动槽函数
void MainWindow::on_Slider_valueChanged(int value)
{
   ui->label_km->setText(QString("单位KM,当前半径范围:%1KM").arg(value));
   update();
}
//三点计算夹角
double MainWindow::get_angle(double x1, double y1, double x2, double y2, double vertexX, double vertexY)
{
    double theta = atan2(x1 - vertexX, y1 - vertexY) - atan2(x2 - vertexX, y2 - vertexY);
    theta = fabs(theta * 180.0 / M_PI);
    return theta;
}
//根据坐标计算到原点距离
double MainWindow::get_distance(QPoint point)
{
    int x,y;
    x= center.x()-point.x();
    y= center.y()-point.y();
    return sqrtf(x*x+y*y);
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    double distance = get_distance(event->pos());
    if(distance<r)
    {
        double angle = get_angle(center.x(),0,event->x(),event->y(),center.x(),center.y());
        arr.append("\n Empty Press 方位="+QString::number(angle,'f',1)+"° 距离="+QString::number(distance*ui->Slider->value()/r,'f',1)+"KM;");
        ui->label_show->setText(arr);
        ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->maximum());
    }
}
//R按键槽函数，随机添加目标
void MainWindow::on_pushButton_R_clicked()
{
    QTime randtime;
    randtime = QTime::currentTime();
    int seed = randtime.msec()+randtime.second()*1000;//以当前时间ms为随机种子
    qsrand(seed);
    int id = qrand() % 100;    //产生100以内的随机整数
    int speed = qrand() % 10+1;
    int direction = qrand() % 360;
    info_t info;
    info.id = id;
    info.color = 0;
    info.speed = speed;
    info.direction = direction;
    info.x = (qrand()%(r)-qrand()%(r));
    info.y = (qrand()%(r)-qrand()%(r));
    info.Slidervalue = ui->Slider->value();
    target.prepend(info);
    if(!timer_target.isActive())
        timer_target.start(1000);
    update();
}
//T按键槽函数->收起/展开目标数据展示区
void MainWindow::on_pushButton_T_clicked()
{
    if(ui->scrollArea->height()>0)
    {
        closed = false;
        ui->scrollArea->setMinimumHeight(0);
    }
    else
    {
        closed = true;
        ui->scrollArea->setMaximumHeight(scrollArea_maxh);
    }
    timer_h.start(10);
}
//目标数据展示区的展开与收起实现
void MainWindow::h_update()
{
    if(closed)//展开
    {
        if(scrollArea_maxh - ui->scrollArea->height()>20)
            ui->scrollArea->setMinimumHeight(ui->scrollArea->height()+20);
        else
        {
            ui->scrollArea->setMinimumHeight(scrollArea_maxh);
            timer_h.stop();
            closed = false;
        }
    }
    else//收起
    {
        if(ui->scrollArea->maximumHeight()>20)
            ui->scrollArea->setMaximumHeight(ui->scrollArea->height()-20);
        else
        {
            ui->scrollArea->setMaximumHeight(0);
            timer_h.stop();
            closed = true;
        }
    }
}
//C按键槽函数->清空目标数据展示区->清空目标容器
void MainWindow::on_pushButton_C_clicked()
{
    ui->label_show->setText(" 目标数据展示区");
    target.clear();
    update();
}
//L按键槽函数
void MainWindow::on_pushButton_L_clicked()
{
    connect(buttonl,SIGNAL(senddata_l(int,int)),this,SLOT(recdata_l(int,int)));
    buttonl->exec();
}
//接受L按键的弹窗窗口的数据的槽函数（激光设置数据）
void MainWindow::recdata_l(int dir,int dis)
{
    datal.dir=dir;
    datal.dis=dis;
    datal_dis_temp = 0;
}
//激光的发射过程时钟
void MainWindow::l_update()
{
    if(datal_dis_temp == datal.dis){
        datal_dis_temp = 0;
    }
    else if(datal.dis - datal_dis_temp > 5){
        datal_dis_temp+=5;
    }
    else if(datal.dis - datal_dis_temp <= 5){
        datal_dis_temp = datal.dis;
    }
    update();
}
//接受D按键的弹窗窗口的数据的槽函数（警告区域设置数据）
void MainWindow::recdata_d(int danger,QString info,int stardir,int enddir,int near,int far)
{
    data_d datad;
    datad.danger = danger;
    datad.enddir = enddir;
    datad.far = far;
    datad.info = info;
    datad.near = near;
    datad.stardir = stardir;
    data_d_v.prepend(datad);
    update();
}
//按键D的槽函数
void MainWindow::on_pushButton_D_clicked()
{
    connect(buttond,SIGNAL(senddata_d(int,QString,int,int,int,int)),this,SLOT(recdata_d(int,QString,int,int,int,int)));
    buttond->exec();
}
//重写窗口mousePressEvent函数实现右键菜单
void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if(event->buttons()==Qt::RightButton)
    {
        //然后判断鼠标位置是否在text内.
        double distance = get_distance(event->pos());
        if(distance<r)
            {
                QMenu * menu=new QMenu;
                QAction * action=new QAction;
                action->setText("添加目标");
                connect(action,SIGNAL(triggered(bool)),this,SLOT(btn_addtarget_clicked()));
                menu->addAction(action);
                menu->exec(event->globalPos());
            }
    }
}
//右键菜单 添加目标 的按键槽函数
void MainWindow::btn_addtarget_clicked()
{
    connect(addtarget,SIGNAL(send_data(int,QString,int,int,int,int,int)),this,SLOT(recdata_addtarget(int,QString,int,int,int,int,int)));
    addtarget->exec();
}
//接收添加指定目标的窗口发来的数据的槽函数（指定目标的 方位，航向，速度等信息）
void MainWindow::recdata_addtarget(int id,QString type,int color,int stardir,int movedir,int dis,int speed)
{
    info_t info;
    info.id = id;
    info.speed = speed;
    info.direction = movedir;
    info.x = dis*qCos((90-stardir)/180.0*M_PI)*r/ui->Slider->value();
    info.y = -dis*qSin((90-stardir)/180.0*M_PI)*r/ui->Slider->value();
    info.Slidervalue = ui->Slider->value();
    info.color = color;
    target.prepend(info);
    if(!timer_target.isActive())
        timer_target.start(1000);
    update();
}
